package com.jml.二期.HashMap003;

public class Jdk7HashMap<K, V> implements JmlMap<K, V> {
    // 扩容负载因子 0.75
    final float loadFactor;
    // 初始容量默认为16
    static final int DEFAULT_INITIAL_CAPACITY = 16;
    /**
     * 负载因子，默认为0.75 负载因子越低 hash冲突也就越低
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;
    /**
     * 负载因子
     */
    int threshold;

    /**
     * hashMap存放数据
     */
    Entry[] table;
    /**
     * 集合中的大小
     */
    transient int size;

    public Jdk7HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
        /**
         * 空方法 能够给子类实现扩展
         */
        init();
    }

    void init() {}

    @Override
    public int size() {
        return 0;
    }

    @Override
    public V put(K key, V value) {
        // 1.计算hash值
        int hash = hash(key);
        // 计算index
        int i = indexFor(hash, table.length);
        // 判断是否有hash碰撞的问题，如果发生hash碰撞问题，hashCode相同且对象的值内容不同
        for (Entry<K, V> e = table[i]; e != null; e = e.next) {
            if (e.getKey().equals(key)) {
                // 获取原来的值
                V oldValue = e.getValue();
                // 设置新值
                e.setValue(value);
                return oldValue;
            }
        }
        // 如果没有发生hash碰撞问题，链表中添加元素
        addEntry(hash, key, value, i);
        return null;
    }

    private void addEntry(int hash, K key, V value, int bucketIndex) {
        // 获取Entry对象
        Entry<K, V> e = table[bucketIndex];
        table[bucketIndex] = new Entry(key, value, e, hash);
    }

    static int indexFor(int h, int length) {
        return h & (length - 1);
    }

    @Override
    public V get(K key) {
        return null;
    }

    private int hash(K key) {
        int hashCode = key.hashCode();
        int hash = hashCode % table.length;
        return hash;
    }

    class Entry<K, V> implements JmlMap.Entry<K, V> {
        // key
        private K k;
        // value
        private V v;
        // 下一个节点
        Entry<K, V> next;
        /**
         * hash值
         */
        private int hash;

        public Entry(K k, V v, Entry<K, V> next, int hash) {
            this.k = k;
            this.v = v;
            this.next = next;
            this.hash = hash;
        }

        @Override
        public K getKey() {
            return this.k;
        }

        @Override
        public V getValue() {
            return this.v;
        }

        @Override
        public V setValue(V value) {
            this.v = v;
            return this.v;
        }

        public Entry(K k, V v) {
            this.k = k;
            this.v = v;
        }

    }
}
